﻿#ifndef SINGLETON_H
#define SINGLETON_H

#include <QMutex>
#include <QMutexLocker>

using namespace std;
template <typename T>
class Singleton
{
public:
    static void Release()
    {
        if (nullptr != m_pInstance)
        {
            QMutexLocker Lock(&m_mutex);
            if (nullptr != m_pInstance)
            {
                delete m_pInstance;
            }
        }
    }

    template<typename... Args>
    static T* GetInstance(Args&& ... args)
    {
        if (nullptr == m_pInstance)
        {
            QMutexLocker Lock(&m_mutex);
            if (nullptr == m_pInstance)
            {
                m_pInstance = new T(std::forward<Args>(args)...);
            }
        }

        return m_pInstance;
    }

    Singleton(Singleton &&) = delete;
    Singleton(const Singleton &) = delete;
    Singleton& operator = (const Singleton &) = delete;

private:
    Singleton(){}
    virtual ~Singleton(){}

private:
    static T* m_pInstance;
    static QMutex m_mutex;
};

template<typename T>
QMutex Singleton<T>::m_mutex;

template<typename T>
T* Singleton<T>::m_pInstance = nullptr;

#endif // SINGLETON_H
